﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace MultiDAQ_Analysis.Util
{
    /// <summary>
    /// 高速UDP数据监听采集工具类
    /// </summary>
    public class UdpHighSpeedListener : IDisposable
    {
        // 配置参数
        public int ListenPort { get; set; } = 8080;
        public int ReceiveBufferSize { get; set; } = 64 * 1024 * 1024;
        public int ParseThreadCount { get; set; } = 8;
        public int MaxQueueSize { get; set; } = 500000;
        public int MaxParsedDataCount { get; set; } = 10000000;
        public bool EnableDataParsing { get; set; } = true;

        // 网络组件
        private UdpClient udpClient;
        private volatile bool listening = false;

        // 多线程组件
        private Thread receiveThread;
        private Thread[] parseThreads;
        private Thread uiUpdateThread;
        private Thread performanceThread;

        // 高性能队列
        private readonly ConcurrentQueue<UdpPacket> receiveQueue = new ConcurrentQueue<UdpPacket>();
        private readonly ConcurrentQueue<VoltagePoint> voltageQueue = new ConcurrentQueue<VoltagePoint>();

        // 性能统计
        private  long totalBytesReceived = 0;
        private  long totalPacketsReceived = 0;
        private  long parsedPointCount = 0;
        private  long errorCount = 0;
        private DateTime performanceStartTime;

        // 线程安全的属性访问
        public long TotalBytesReceived => Interlocked.Read(ref totalBytesReceived);
        public long TotalPacketsReceived => Interlocked.Read(ref totalPacketsReceived);
        public long ParsedPointCount => Interlocked.Read(ref parsedPointCount);
        public long ErrorCount => Interlocked.Read(ref errorCount);


        // 事件委托
        public event Action<string> OnLogMessage;
        public event Action<string> OnErrorMessage;
        public event Action<PerformanceStats> OnPerformanceUpdate;
        public event Action<List<VoltagePoint>> OnVoltageDataReceived;
        public event Action<ProtocolFrame> OnProtocolFrameReceived;

        private bool disposed = false;

        public UdpHighSpeedListener(int listenPort = 5000)
        {
            ListenPort = listenPort;
        }

        /// <summary>
        /// 启动高速监听
        /// </summary>
        public bool StartListening()
        {
            try
            {
                if (listening)
                {
                    OnErrorMessage?.Invoke("监听已在进行中");
                    return false;
                }

                // 初始化UDP客户端
                udpClient = new UdpClient(ListenPort);
                udpClient.Client.ReceiveBufferSize = ReceiveBufferSize;
                udpClient.Client.SendBufferSize = 8 * 1024 * 1024;

                // 重置统计
                listening = true;
                performanceStartTime = DateTime.Now;
                ResetStatistics();

                // 清空队列
                ClearQueues();

                // 启动接收线程
                receiveThread = new Thread(HighPerformanceReceiveLoop)
                {
                    IsBackground = true,
                    Name = "UdpReceiver-Main",
                    Priority = ThreadPriority.Highest
                };
                receiveThread.Start();

                // 启动解析线程
                if (EnableDataParsing)
                {
                    StartParseThreads();
                }

                // 启动UI更新线程
                StartUIUpdateThread();

                // 启动性能监控线程
                StartPerformanceMonitorThread();

                OnLogMessage?.Invoke($"高性能监听已启动 - 端口: {ListenPort}, 解析线程: {(EnableDataParsing ? ParseThreadCount : 0)}");
                return true;
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"启动监听失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 停止监听
        /// </summary>
        public bool StopListening()
        {
            try
            {
                if (!listening)
                    return true;

                OnLogMessage?.Invoke("正在停止监听...");
                listening = false;

                // 等待接收线程结束
                if (receiveThread?.IsAlive == true)
                {
                    receiveThread.Join(3000);
                }

                // 等待解析线程结束
                if (parseThreads != null)
                {
                    foreach (var thread in parseThreads)
                    {
                        thread?.Join(2000);
                    }
                }

                // 等待其他线程结束
                uiUpdateThread?.Join(1000);
                performanceThread?.Join(1000);

                // 释放UDP客户端
                udpClient?.Close();
                udpClient = null;

                // 清理线程引用
                receiveThread = null;
                parseThreads = null;
                uiUpdateThread = null;
                performanceThread = null;

                OnLogMessage?.Invoke("监听已停止");
                return true;
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"停止监听时发生错误: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 高性能接收循环
        /// </summary>
        private void HighPerformanceReceiveLoop()
        {
            var localEP = new IPEndPoint(IPAddress.Any, 0);
            long localReceivedCount = 0;
            long localErrorCount = 0;

            // 缓冲区池
            var bufferPool = new ConcurrentBag<byte[]>();
            const int POOL_SIZE = 1000;

            for (int i = 0; i < POOL_SIZE; i++)
            {
                bufferPool.Add(new byte[65507]);
            }

            OnLogMessage?.Invoke($"接收线程已启动，缓冲区池大小: {POOL_SIZE}");

            while (listening)
            {
                try
                {
                    byte[] receivedData = udpClient.Receive(ref localEP);

                    if (receivedData == null || receivedData.Length == 0)
                        continue;

                    localReceivedCount++;
                    // 使用 Interlocked 进行原子操作
                    Interlocked.Add(ref totalBytesReceived, receivedData.Length);
                    Interlocked.Increment(ref totalPacketsReceived);


                    // 从池中获取缓冲区
                    if (!bufferPool.TryTake(out byte[] buffer))
                    {
                        buffer = new byte[65507];
                    }

                    int dataLength = Math.Min(receivedData.Length, buffer.Length);
                    Buffer.BlockCopy(receivedData, 0, buffer, 0, dataLength);

                    var udpPacket = new UdpPacket
                    {
                        Data = buffer,
                        DataLength = dataLength,
                        RemoteEndPoint = localEP,
                        Timestamp = DateTime.Now
                    };

                    receiveQueue.Enqueue(udpPacket);

                    // 队列溢出保护
                    if (receiveQueue.Count > MaxQueueSize)
                    {
                        int discardCount = 0;
                        while (receiveQueue.Count > MaxQueueSize * 0.8 && receiveQueue.TryDequeue(out UdpPacket discarded))
                        {
                            bufferPool.Add(discarded.Data);
                            discardCount++;
                        }

                        if (discardCount > 0)
                        {
                            Interlocked.Add(ref errorCount, discardCount);
                            OnLogMessage?.Invoke($"队列溢出，丢弃 {discardCount} 个包");
                        }
                    }
                }
                catch (Exception ex)
                {
                    localErrorCount++;
                    Interlocked.Increment(ref errorCount);

                    if (listening && localErrorCount % 1000 == 1)
                    {
                        OnErrorMessage?.Invoke($"接收错误: {ex.Message} (已发生{localErrorCount}次)");
                    }
                }
            }

            OnLogMessage?.Invoke($"接收线程结束 - 共接收: {localReceivedCount:N0} 包, 错误: {localErrorCount}");
        }

        /// <summary>
        /// 启动解析线程
        /// </summary>
        private void StartParseThreads()
        {
            parseThreads = new Thread[ParseThreadCount];
            for (int i = 0; i < ParseThreadCount; i++)
            {
                parseThreads[i] = new Thread(HighPerformanceParseLoop)
                {
                    IsBackground = true,
                    Name = $"DataParser-{i}",
                    Priority = ThreadPriority.AboveNormal
                };
                parseThreads[i].Start();
            }
        }

        /// <summary>
        /// 高性能解析循环
        /// </summary>
        private void HighPerformanceParseLoop()
        {
            const int ADC_DATA_WIDTH = 16;
            const double VOL_RANGE = 5.0;
            const int SAMPLE_RATE = 2000000;
            double LSB = VOL_RANGE * 2 / Math.Pow(2, ADC_DATA_WIDTH);

            var localBatch = new List<VoltagePoint>(5000);
            long localErrorCount = 0;
            long localProcessedCount = 0;

            while (listening || !receiveQueue.IsEmpty)
            {
                try
                {
                    for (int i = 0; i < 500 && receiveQueue.TryDequeue(out UdpPacket packet); i++)
                    {
                        localProcessedCount++;

                        //// 处理协议帧
                        //if (IsProtocolFrame(packet.Data, packet.DataLength))
                        //{
                        //    ProcessProtocolFrame(packet);
                        //    continue;
                        //}

                        // 解析ADC数据
                        if (EnableDataParsing && packet.DataLength >= 2)
                        {
                            ParseADCData(packet.Data, packet.DataLength, packet.RemoteEndPoint,
                                        packet.Timestamp, localBatch, LSB, SAMPLE_RATE);
                        }
                    }

                    // 批量处理解析的数据点
                    if (localBatch.Count > 0)
                    {
                        foreach (var point in localBatch)
                        {
                            voltageQueue.Enqueue(point);
                        }

                        Interlocked.Add(ref parsedPointCount, localBatch.Count);
                        localBatch.Clear();

                        // 限制队列大小
                        while (voltageQueue.Count > MaxParsedDataCount)
                        {
                            voltageQueue.TryDequeue(out _);
                        }
                    }

                    if (receiveQueue.IsEmpty)
                    {
                        Thread.Sleep(1);
                    }
                }
                catch (Exception ex)
                {
                    localErrorCount++;
                    Interlocked.Increment(ref errorCount);

                    if (localErrorCount % 1000 == 1)
                    {
                        OnErrorMessage?.Invoke($"解析错误 {Thread.CurrentThread.Name}: {ex.Message}");
                    }
                    Thread.Sleep(10);
                }
            }

            OnLogMessage?.Invoke($"解析线程结束 {Thread.CurrentThread.Name} - 处理: {localProcessedCount:N0} 包, 错误: {localErrorCount}");
        }

        /// <summary>
        /// 解析ADC数据
        /// </summary>
        private void ParseADCData(byte[] rawData, int dataLength, IPEndPoint remoteEP, DateTime timestamp,
            List<VoltagePoint> batch, double LSB, int sampleRate)
        {
            double sampleInterval = 1000000.0 / sampleRate;

            for (int i = 0; i < dataLength - 1; i += 2)
            {
                int adcCode = rawData[i] | (rawData[i + 1] << 8);

                if (adcCode > (1 << 15))
                {
                    adcCode -= (1 << 16);
                }

                double voltage = adcCode * LSB - LSB / 2;
                double sampleTimeUs = sampleInterval * (i / 2 + 1);
                DateTime sampleTime = timestamp.AddTicks((long)(sampleTimeUs * 10));

                batch.Add(new VoltagePoint(sampleTime, voltage, i / 2, remoteEP.ToString()));
            }
        }

        /// <summary>
        /// 处理协议帧
        /// </summary>
        private void ProcessProtocolFrame(UdpPacket packet)
        {
            try
            {
                if (packet.DataLength >= 8)
                {
                    byte reg = packet.Data[2];
                    uint data = (uint)(packet.Data[3] << 24) | (uint)(packet.Data[4] << 16) |
                               (uint)(packet.Data[5] << 8) | (uint)packet.Data[6];

                    var frame = new ProtocolFrame
                    {
                        RegisterAddress = reg,
                        Data = data,
                        RemoteEndPoint = packet.RemoteEndPoint,
                        Timestamp = packet.Timestamp
                    };

                    OnProtocolFrameReceived?.Invoke(frame);
                }
            }
            catch (Exception ex)
            {
                OnErrorMessage?.Invoke($"协议帧解析错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 启动UI更新线程
        /// </summary>
        private void StartUIUpdateThread()
        {
            uiUpdateThread = new Thread(UIUpdateLoop)
            {
                IsBackground = true,
                Name = "UIUpdater",
                Priority = ThreadPriority.BelowNormal
            };
            uiUpdateThread.Start();
        }

        /// <summary>
        /// UI更新循环
        /// </summary>
        private void UIUpdateLoop()
        {
            var displayBatch = new List<VoltagePoint>(1000);

            while (listening || !voltageQueue.IsEmpty)
            {
                try
                {
                    for (int i = 0; i < 1000 && voltageQueue.TryDequeue(out VoltagePoint point); i++)
                    {
                        displayBatch.Add(point);
                    }

                    if (displayBatch.Count > 0)
                    {
                        OnVoltageDataReceived?.Invoke(new List<VoltagePoint>(displayBatch));
                        displayBatch.Clear();
                    }
                    else
                    {
                        Thread.Sleep(20);
                    }
                }
                catch (Exception ex)
                {
                    OnErrorMessage?.Invoke($"UI更新错误: {ex.Message}");
                    Thread.Sleep(100);
                }
            }
        }

        /// <summary>
        /// 启动性能监控线程
        /// </summary>
        private void StartPerformanceMonitorThread()
        {
            performanceThread = new Thread(PerformanceMonitorLoop)
            {
                IsBackground = true,
                Name = "PerformanceMonitor"
            };
            performanceThread.Start();
        }

        /// <summary>
        /// 性能监控循环
        /// </summary>
        private void PerformanceMonitorLoop()
        {
            while (listening)
            {
                try
                {
                    var elapsed = DateTime.Now - performanceStartTime;
                    if (elapsed.TotalSeconds > 0)
                    {
                        var stats = new PerformanceStats
                        {
                            TotalBytesReceived = totalBytesReceived,
                            TotalPacketsReceived = totalPacketsReceived,
                            ParsedPointCount = parsedPointCount,
                            ErrorCount = errorCount,
                            ReceiveQueueCount = receiveQueue.Count,
                            VoltageQueueCount = voltageQueue.Count,
                            ElapsedTime = elapsed,
                            ReceiveSpeedMBps = (totalBytesReceived / 1024.0 / 1024.0) / elapsed.TotalSeconds,
                            PacketRatePps = totalPacketsReceived / elapsed.TotalSeconds,
                            ParseRatePointsPerSecond = parsedPointCount / elapsed.TotalSeconds
                        };

                        OnPerformanceUpdate?.Invoke(stats);
                    }

                    Thread.Sleep(1000);
                }
                catch (Exception ex)
                {
                    OnErrorMessage?.Invoke($"性能监控错误: {ex.Message}");
                    Thread.Sleep(1000);
                }
            }
        }

        /// <summary>
        /// 判断是否为协议帧
        /// </summary>
        private static bool IsProtocolFrame(byte[] bytes, int length)
        {
            return bytes != null && length >= 8 &&
                   bytes[0] == 0x55 && bytes[1] == 0xA5 && bytes[7] == 0xF0;
        }

        /// <summary>
        /// 重置统计信息
        /// </summary>
        public void ResetStatistics()
        {
            Interlocked.Exchange(ref totalBytesReceived, 0);
            Interlocked.Exchange(ref totalPacketsReceived, 0);
            Interlocked.Exchange(ref parsedPointCount, 0);
            Interlocked.Exchange(ref errorCount, 0);
            performanceStartTime = DateTime.Now;
        }

        /// <summary>
        /// 清空队列
        /// </summary>
        public void ClearQueues()
        {
            while (receiveQueue.TryDequeue(out _)) { }
            while (voltageQueue.TryDequeue(out _)) { }
        }

        public void Dispose()
        {
            if (!disposed)
            {
                StopListening();
                disposed = true;
            }
        }
    }

    // 数据结构定义
    public struct UdpPacket
    {
        public byte[] Data;
        public int DataLength;
        public IPEndPoint RemoteEndPoint;
        public DateTime Timestamp;
    }

    public struct VoltagePoint
    {
        public DateTime Timestamp { get; set; }
        public double Voltage { get; set; }
        public int SampleIndex { get; set; }
        public string Source { get; set; }

        public VoltagePoint(DateTime timestamp, double voltage, int sampleIndex, string source)
        {
            Timestamp = timestamp;
            Voltage = voltage;
            SampleIndex = sampleIndex;
            Source = source;
        }
    }

    public struct ProtocolFrame
    {
        public byte RegisterAddress { get; set; }
        public uint Data { get; set; }
        public IPEndPoint RemoteEndPoint { get; set; }
        public DateTime Timestamp { get; set; }
    }

    public struct PerformanceStats
    {
        public long TotalBytesReceived { get; set; }
        public long TotalPacketsReceived { get; set; }
        public long ParsedPointCount { get; set; }
        public long ErrorCount { get; set; }
        public int ReceiveQueueCount { get; set; }
        public int VoltageQueueCount { get; set; }
        public TimeSpan ElapsedTime { get; set; }
        public double ReceiveSpeedMBps { get; set; }
        public double PacketRatePps { get; set; }
        public double ParseRatePointsPerSecond { get; set; }
    }
}
